<template>
  <a-row class="grid">
    <a-col class="content" :span="16">
      <div class="content-header">

      </div>
      <div id="screen">
        <div class="expression">
          {{ expression }}
        </div>
        <div class="res">
          {{ res }}
        </div>
      </div>
      <div id="control">
        <button @click="input('C')"> C</button>
        <button @click="input('+')">+</button>
        <button @click="input('-')">-</button>
        <button @click="input('<-')"><-</button>
        <button @click="input('7')">7</button>
        <button @click="input('8')">8</button>
        <button @click="input('9')">9</button>
        <button @click="input('*')">*</button>
        <button @click="input('4')">4</button>
        <button @click="input('5')">5</button>
        <button @click="input('6')">6</button>
        <button @click="input('/')">/</button>
        <button @click="input('1')">1</button>
        <button @click="input('2')">2</button>
        <button @click="input('3')">3</button>
        <button @click="input('=')" style="grid-row: 4/6;grid-column: 4">=</button>
        <button @click="input('0')" style="grid-row: 5;grid-column: 1/3">0</button>
        <button @click="input('.')">.</button>
      </div>
    </a-col>
    <a-col class="sider" :span=8>
      <div class="sider-header">
        <button class="getHistory" @click="getHistory">更新历史记录</button>
        <div id="query-config">
          <input class="query-config-item" v-model="queryFrom" placeholder="from sql or file"></input>
          <input class="query-config-item" v-model="queryPage" placeholder="page"></input>
          <input class="query-config-item" v-model="querySize" placeholder="size of page"></input>
        </div>

      </div>
      <div class="history-list">
        <div class="history-list-item" v-for="item in history">
          <h2 class="date">{{ item.date.substring(0, item.date.length - 10) }}</h2>
          <span class="history-list-item-map">
            <span class="key">表达式:</span>
            <span class="value">{{ item.expression }}</span>
          </span>
          <span class="history-list-item-map">
            <span class="key">结果:</span>
            <span class="value">{{ item.res }}</span>
          </span>
          <span class="history-list-item-map">
            <span class="key">用时:</span>
            <span class="value">{{ item.duration }}ms</span>
          </span>
        </div>
      </div>
    </a-col>
  </a-row>
</template>
<script setup lang="ts">
import axios from 'axios'
import {onMounted, reactive, ref} from "vue";
import {Notification} from '@arco-design/web-vue';

const developmentUrl = "http://localhost:8080";
const testUrl = "http://8.140.197.66:8080";
const baseUrl = testUrl;
const operatorSet = [
  '+', '-', '*', '/'
];
const history = reactive([]);
const expression = ref("");
const res = ref("");
const queryFrom = ref("sql");
const queryPage = ref(0);
const querySize = ref(10);

const getHistory = () => {

  if (queryFrom.value != "sql" && queryFrom.value != 'file') {
    Notification.error('sql or file');
    return;
  } else if ((typeof queryPage.value === 'number' || /^\d+$/.test(queryPage.value)) && queryPage.value % 1 === 0 && queryPage.value >= 0
      && (typeof querySize.value === 'number' || /^\d+$/.test(querySize.value)) && querySize.value % 1 === 0 && querySize.value > 0) {
    axios({
      method: "get",
      url: baseUrl + "/calculate",
      params: {
        from: queryFrom.value,
        page: queryPage.value,
        size: querySize.value
      }
    }).then(({data}) => {
      history.splice(0, history.length, ...data?.data);
    })
  } else {
    Notification.error('别搞');
  }
}

const calculate = () => {
  let expressionLength = expression.value.length;
  let lastChar = expressionLength > 0 ? expression.value[expressionLength - 1] : '';
  let prefixExpression = expressionLength != 0 ? expression.value.substring(0, expression.value.length - 1) : "";
  while (operatorSet.indexOf(lastChar) != -1) {
    expression.value = prefixExpression;
    expressionLength = expression.value.length;
    lastChar = expressionLength > 0 ? expression.value[expressionLength - 1] : '';
    prefixExpression = expressionLength == 0 ? expression.value.substring(0, expression.value.length - 1) : "";
  }

  expression.value = expression.value.replace(/-([\d.]+)/g, '+(-$1)')
  axios({
    method: "post",
    url: baseUrl + "/calculate",
    data: {
      expression: expression.value
    }
  }).then(({data}) => {
    expression.value = "";
    res.value = data?.data;
  }).catch(() => {
    res.value = "Error"
  })
}
const pointFlag = ref(false);
const input = (cmd: string) => {
  expression.value = String(expression.value);
  let expressionLength = expression.value.length;
  let lastChar = expressionLength > 0 ? expression.value[expressionLength - 1] : '';
  let prefixExpression = expressionLength > 1 ? expression.value.substring(0, expressionLength - 1) : "";
  if (res.value == "Calculating") {
    return;
  } else if (cmd == "C") {
    expression.value = res.value;
    res.value = "";
  } else if (cmd == "<-") {
    expression.value = prefixExpression;
  } else if (operatorSet.indexOf(cmd) != -1) {
    if (expression.value.length == 0) {
      expression.value = res.value;
      expressionLength = expression.value.length;
      lastChar = expressionLength > 0 ? expression.value[expressionLength - 1] : '';
      prefixExpression = expressionLength > 1 ? expression.value.substring(0, expressionLength - 1) : "";
      res.value = "";
    }
    if (cmd != '-' && expressionLength == 0) {
      return;
    } else if (operatorSet.indexOf(lastChar) != -1 || lastChar == '.') {
      expression.value = prefixExpression + cmd;
    } else {
      expression.value = expression.value + cmd;
      pointFlag.value = false;
    }
  } else if (cmd == '=') {
    calculate();
    res.value = "Calculating"
    pointFlag.value = false;
  } else if (cmd == '.') {
    if (lastChar != '.' && !pointFlag.value && operatorSet.indexOf(lastChar) == -1) {
      expression.value = expression.value + cmd;
      pointFlag.value = true;
    }
  } else {
    expression.value = expression.value + cmd;
  }
}
const updateFontSize = () => {
  const root = document.documentElement;
  const controlDom = document.getElementById("control");
  const buttons = controlDom.querySelector("button");
  const buttonsHeight = buttons.clientHeight * 0.3;
  root.style.setProperty("--font-size-button", buttonsHeight + 'px');
  const screenDom = document.getElementById("screen");
  const screenHeight = screenDom.clientHeight;
  const expressionHeight = screenHeight * 0.2;
  root.style.setProperty("--font-size-expression", expressionHeight + 'px');
  const resHeight = screenHeight * 0.4;
  root.style.setProperty("--font-size-res", resHeight + 'px');
}
onMounted(() => {
  updateFontSize();
  const expressions = document.querySelectorAll('.expression, .res');
  expressions.forEach(expression => {
    expression.addEventListener("wheel", (event: WheelEvent) => {
      if (event.deltaY) {
        event.preventDefault();
        expression.scrollLeft += Number(event.deltaY);
      }
    })
  })
})
window.addEventListener("resize", updateFontSize);
</script>

<style scoped>
:root {
  --font-size-button: 1rem;
  --font-size-expression: 1rem;
  --font-size-res: 1rem;
}

.grid {
  height: 100vh;
  width: 100vw;
  background-color: var(--color-fill-3);
}

.content {
  height: 100%;
  border-radius: 10px;
  padding: 10px;
  display: flex;
  flex-direction: column;

  #screen {
    height: 25vh;
    background-color: var(--color-white);
    border-radius: 10px;
    padding: 10px;
    display: flex;
    flex-direction: column;
    white-space: nowrap;
    justify-content: space-around;

    .expression, .res {
      color: var(--color-text-3);
      font-size: var(--font-size-expression);
      display: block;
      overflow-x: scroll;
      overflow-y: hidden;
      width: 100%;
      scrollbar-width: none;
      line-height: 1.35;
      text-align: right;
    }

    .res {
      color: var(--color-text-2);
      font-size: var(--font-size-res);
    }
  }

  #control {
    border-radius: 10px;
    margin-top: 10px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(5, 1fr);
    grid-gap: 10px;
    flex: 1;

    button {
      background-color: var(--color-fill-1);
      border: none;
      border-radius: 10px;
      transition: background-color 0.25s;
      user-select: none;
      font-size: var(--font-size-button);

      &:hover {
        background-color: var(--color-white);
      }

      &:active {
        background-color: var(--color-fill-4);
      }
    }
  }
}


.history-list {
  flex: 1;
  display: block;
  overflow-y: scroll;
  scrollbar-width: none;
  background-color: var(--color-fill-4);
  border-radius: 10px;
  padding: 10px;

  .history-list-item {
    line-height: 1.35;
    padding: 4px 6px;
    border-radius: 10px;
    transition: background-color 0.25s;
    overflow-x: hidden;

    &:hover {
      background-color: var(--color-fill-1);
    }

    .date {
      width: 100%;
      text-align: left;
      font-size: 1rem;
      color: var(--color-text-3);
    }

    .history-list-item-map {
      display: inline-block;
      line-height: 2.5;
      margin-right: 5px;
      white-space: nowrap;

      .key {
        margin-right: 5px;
      }

      .value {
        background-color: var(--color-fill-2);
        padding: 3px 10px;
        border-radius: 2px;
        color: var(--color-text-3);
      }
    }

  }
}


.sider {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 10px;
  padding: 10px;

  .getHistory {
    width: 100%;
    height: 50px;
    border-radius: 10px;
    border: none;
    user-select: none;
    transition: background-color 0.3s;
    background-color: var(--color-fill-4);

    &:hover {
      background-color: var(--color-white);
    }

    &:active {
      background-color: var(--color-fill-3);
      transition: background-color 0.1s;
    }
  }

  #query-config {
    margin: 10px 0;
    display: flex;
    justify-content: space-between;
    gap: 10px;

    .query-config-item {
      background-color: var(--color-fill-4);
      padding: 10px;
      border-radius: 10px;
      width: 30%;
      border: none;
      text-align: center;

      input {
        border: none;
        background-color: transparent;

        &:focus {
          outline: none;
        }
      }
    }
  }
}
</style>
